package a2_p04_ak_fh;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.JFrame;
import javax.swing.DefaultDesktopManager;

import org.jgraph.graph.DefaultEdge;
import org.jgraph.graph.GraphConstants;
import org.jgrapht.DirectedGraph;
import org.jgrapht.Graph;
import org.jgrapht.WeightedGraph;
import org.jgrapht.graph.DefaultDirectedGraph;
import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.SimpleGraph;

import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.util.mxConstants;
import com.mxgraph.view.mxGraph;

public class GraphVis extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private GraphVis(Graph<AttVertex, DefaultWeightedEdge> g, Integer o,
			List<AttVertex> vertexlist) {

		int i = 1, x = 1;
		int y = 1;
		AttVertex s, t;

		mxGraph graph = new mxGraph();
		Object parent = graph.getDefaultParent();
		HashMap<String, Object> visitedvertex = new HashMap<String, Object>();
		graph.getModel().beginUpdate();

		Set<DefaultWeightedEdge> edges = g.edgeSet();
		String order = "", order2 = "";
		
		// Style informations
		System.out.println("#######################################");
		if (o == 1) {
			order = "startArrow=none;endArrow=none;strokeWidth=2;strokeColor=#F00F00";
			order2 = "startArrow=none;endArrow=none;strokeWidth=4;strokeColor=#0000ff";
		} else {
			order = "strokeWidth=2;strokeColor=#f00000";
			order2 = "strokeWidth=4;strokeColor=#0000ff";
		}
		try {

			// Going to each edge of the graph
			for (DefaultWeightedEdge e : edges) {
				// Source already visited?
				s = g.getEdgeSource(e);
				t = g.getEdgeTarget(e);
				if (!visitedvertex.containsKey(s.getName())) {
					// put source to visited vertex list and add the vertex to
					// the visualisation
					visitedvertex.put(s.getName(), graph.insertVertex(parent,
							null, s, i * 100, y * 150+(i*10+(i%2*-10)), 20, 20));
				}
				// Target already visited?
				if (!visitedvertex.containsKey(t.getName())) {
					// put target to visited vertex list and add the vertex to
					// the visualisation
					visitedvertex.put(t.getName(), graph.insertVertex(parent,
							null, t, i * 200, y * 300+(x*10+(i%2*-10)), 20, 20));
				}
				
					graph.insertEdge(parent, null, g.getEdgeWeight(e),
							visitedvertex.get(s.getName()),
							visitedvertex.get(t.getName()), order);
			
				if (i == 10) {
					i = 1;
					y++;
				}
				i++;
				x++;

			}
			if (!vertexlist.isEmpty()) {
				updateMod(graph,g,vertexlist,visitedvertex,parent,order2);
			}
		} finally {
			graph.getModel().endUpdate();
		}

		mxGraphComponent graphComponent = new mxGraphComponent(graph);
		getContentPane().add(graphComponent);

	}

	private void updateMod(mxGraph graph,Graph<AttVertex, DefaultWeightedEdge> g,List<AttVertex> vertexlist,HashMap<String, Object> visitedvertex,Object parent,String order){
			for (int i = 0; i < vertexlist.size()-1; i++) {
				AttVertex sa = vertexlist.get(i);
				AttVertex ta = vertexlist.get(i+1);
				Object s = visitedvertex.get(sa.getName());
				Object t = visitedvertex.get(ta.getName());
				Set<DefaultWeightedEdge> edges = g.edgeSet();
				for (DefaultWeightedEdge edge : edges) {
					if((g.getEdgeSource(edge).getName().compareTo(sa.getName())==0) && (g.getEdgeTarget(edge).getName().compareTo(ta.getName())==0)){
						graph.getModel().remove(edge);
						graph.refresh();
					}
				}
				
				graph.insertEdge(parent, null, g.getEdgeWeight(g.getEdge(sa, ta)),s,t,order);
			}
	}
	
	/**
	 * factory methods
	 * 
	 * @param graph
	 *            : Graph/home/fabian/EclipseWorkspace/gka_wise12
	 * @param i
	 *            : 1 for undirected graph else directed
	 */
	public static void startvis(Graph<AttVertex, DefaultWeightedEdge> graph,
			Integer i, List<AttVertex> vertexlist) {
		GraphVis frame = new GraphVis(graph, i, vertexlist);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(400, 320);
		frame.setVisible(true);
	}
	
	
}
